package socket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-10-29
 * Time: 16:59
 */

public class TcpEchoServer {
    //网络编程大前提
    private ServerSocket socket;
    //构造方法指定端口号
    public TcpEchoServer(int port) throws IOException {
        socket = new ServerSocket(port);
    }

    //启动服务器
    public void start() throws IOException {
        System.out.println("启动服务器!");
        while (true){
            //TCP是有有连接的了 连接了才能通讯 只负责接电话
            Socket clientSocket= socket.accept();
            //将业务逻辑交给另一个函数处理
            processConnection(clientSocket);
        }
    }

    //读使用Scanner文件
    //写PrintWriter文件
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("客户端建立连接: " + clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //接下来处理请求和响应
        //TCP是面向字节流 所以这里的读和写都是写字节流读写文件操作一样
        try(InputStream inputStream = clientSocket.getInputStream()){
            try(OutputStream outputStream = clientSocket.getOutputStream()){
                //先读取客户端传来的数据
                //循环处理每一个请求 分别返回响应
                //为了方便 使用scanner从文件中读取数据 构造函数参数是一个文件对象
                //构造一个scanner从这个指定的inputStream文件中扫描
                Scanner scanner = new Scanner(inputStream);
                while (true){
                    //读取请求 hasNext期待有下一个值 若是没有返回false
                    if (!scanner.hasNext()){
                        System.out.printf("客户端断开连接" + clientSocket.getInetAddress().toString(),clientSocket.getPort());
                        break;
                    }
                    //次数使用scanner读文件更加的方便  不用scanner就使用原生的InputStream的read来读文件
                    //客户端和服务器的读写数据方式要对应
                    String request = scanner.next();
                    //2.根据请求计算响应
                    String response = process(request);
                    //3.把响应返回给客户端
                    //方便起见使用PrintWriter包裹OutputStream
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    printWriter.println(response);
                    //最后刷新缓冲区
                    printWriter.flush();

                    System.out.printf("req: %s, resp: %s\n", request, response);
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //记得关闭文件
            clientSocket.close();
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();
    }

}
